<template>
  <div style="padding-left: 20px; padding-right: 20px; padding-top: 20px">
    <div>
      <toolbar
        :buttons="['submit', 'delete', 'back', 'approve', 'print']"
        :table="$refs.xTable"
        @delete="handleDelete"
        @refresh="handleRefresh"
        @submit="handleSubmit"
        @back="handleReturnList"
        @approved="handleApprove"
        @print="handlePrint"
      ></toolbar>
    </div>
    <div style="padding-top: 20px; padding-left: 20px">
      <el-form
        :model="journal"
        :rules="rules"
        ref="journalForm"
        label-width="100px"
        label-position="left"
        :inline="true"
      >
        <el-form-item label="日期" prop="date">
          <el-date-picker
            v-model="journal.date"
            type="date"
            placeholder="选择日期"
            @change="handleDateChange"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="凭证号" prop="number">
          <el-row>
            <el-col :span="4"
              ><journal-word-select
                v-model="journal.numberprefixId"
                placeholder="请选择"
                @change="handleNumberPrefixChange"
                ref="journalNumberPrefix"
              >
              </journal-word-select
            ></el-col>
            <el-col :span="20">
              <el-input
                placeholder="请输入凭证号"
                v-model="journal.number"
                class="input-with-select"
              >
              </el-input
            ></el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="附件" v-show="journal.id">
          <i class="el-icon-folder-opened" @click="handleAttachment"></i>
        </el-form-item>
      </el-form>
    </div>
    <div style="margin-top: 10px; margin-left: 20px; margin-right: 20px">
      <vxe-table
        border
        align="center"
        show-footer
        :data="journal.items"
        auto-resize
        :export-config="{}"
        resizable
        ref="xTable"
        :show-overflow="false"
        @cell-click="handleCellClick"
        size="small"
        :edit-rules="tableRules"
        :mouse-config="{ selected: true }"
        :checkbox-config="{ range: true }"
        :keyboard-config="{
          isArrow: true,
          isDel: false,
          isEnter: true,
          isTab: true,
          isEdit: true,
        }"
        :edit-config="{
          trigger: 'click',
          mode: 'cell',
          activeMethod: handleCellEnableEdit,
        }"
        :footer-method="handleFooterData"
        :merge-footer-items="mergeFooterItems"
      >
        <vxe-table-column type="checkbox" width="60"></vxe-table-column>
        <vxe-table-column type="seq" width="60"></vxe-table-column>
        <vxe-table-column
          field="summary"
          title="摘要"
          align="left"
          header-align="center"
          width="200"
          :edit-render="{
            attrs: {},
            autofocus: '.custom-input',
          }"
        >
          <template #default="{ row }">
            <div>
              {{ row.summary }}
            </div>
          </template>
          <template #edit="{ row }">
            <el-input v-model="row.summary"></el-input>
          </template>
        </vxe-table-column>
        <vxe-table-column
          field="accountId"
          title="科目"
          align="left"
          header-align="center"
          width="230"
          :edit-render="{
            attrs: {},
            autofocus: '.custom-input',
          }"
        >
          <template #default="{ row }">
            <div>
              {{ row.accountFullName }}
            </div>
          </template>
          <template #edit="{ row }">
            <account-select
              v-model="row.accountId"
              optionClass="vxe-table–ignore-clear"
              @change="(node) => handleAccountChange(row, node)"
            ></account-select>
          </template>
        </vxe-table-column>

        <vxe-table-column
          field="dimensionGroupValueId"
          title="核算维度"
          align="left"
          header-align="center"
          :edit-render="{
            enabled: true,
            autoselect: true,
          }"
          :visible="false"
        >
          <template #default="{ row }">
            <dimension-value-panel
              :dimensionItems.sync="row.currentAccount.dimensionItems"
              :dimensionItemValues.sync="row.dimensionGroupValueItems"
            ></dimension-value-panel>
          </template>
          <template #edit="{ row }">
            <dimension-value-select
              :dimensionItems="row.currentAccount.dimensionItems"
              :dimensionItemValues="row.dimensionGroupValueItems"
              v-model="row.dimensionGroupValueId"
              optionClass="vxe-table–ignore-clear"
              @change="(values) => handleDimensionValueChange(row, values)"
            ></dimension-value-select>
          </template>
        </vxe-table-column>
        <vxe-table-column
          field="currencyId"
          title="外币核算"
          align="center"
          header-align="center"
          width="230"
          :edit-render="{
            enabled: true,
            autoselect: true,
          }"
          :visible="false"
        >
          <template #default="{ row }">
            <journal-currency-panel :item="row"></journal-currency-panel>
          </template>
          <template #edit="{ row }">
            <journal-currency-select
              :item="row"
              optionClass="vxe-table–ignore-clear"
              @change="(value) => handleCurrencyChange(row, value)"
            ></journal-currency-select>
          </template>
        </vxe-table-column>
        <vxe-table-column
          field="debitAmount"
          title="借方"
          align="right"
          header-align="center"
          :edit-render="{
            attrs: {},
          }"
        >
          <template #default="{ row }">
            <div>
              <span>{{ row.debitAmount | money }}</span>
            </div>
          </template>
          <template #edit="{ row }">
            <number-input
              v-model="row.debitAmount"
              :precision="2"
              @input="(value) => handleAmountChange(row, 1)"
            ></number-input>
          </template>
        </vxe-table-column>
        <vxe-table-column
          field="creditAmount"
          title="贷方"
          align="right"
          header-align="center"
          :edit-render="{
            attrs: {},
          }"
        >
          <template #default="{ row }">
            <div>
              <span>{{ row.creditAmount | money }}</span>
            </div>
          </template>
          <template #edit="{ row }">
            <number-input
              v-model="row.creditAmount"
              :precision="2"
              @input="(value) => handleAmountChange(row, -1)"
            ></number-input>
          </template>
        </vxe-table-column>

        <template #empty v-if="!readonly">
          <p v-if="readonly">暂无数据</p>
          <el-link v-if="!readonly" @click="handleAddNew" type="primary"
            >新增一行
          </el-link>
        </template>
      </vxe-table>
    </div>
    <el-drawer
      direction="rtl"
      :visible.sync="editAttachmentDrawer"
      :with-header="false"
    >
      <div v-if="editAttachmentDrawer">
        <attachment-panel
          :moduleCode="'journal'"
          :ownerId="journal.id"
        ></attachment-panel>
      </div>
    </el-drawer>
    <print-dialog
      ref="printPanel"
      :moduleCode="'journal'"
      :ids="[this.id]"
    ></print-dialog>
  </div>
</template>
<script>
import {
  getJournal,
  addJournal,
  updateJournal,
  getJournalNextNumber,
} from "@/api/journal";
import toolbar from "@/components/Bar/toolbar.vue";
import dimensionValueSelect from "@/components/Select/dimensionValueSelect.vue";
import dimensionValuePanel from "@/components/Panel/dimensionValuePanel.vue";
import accountSelect from "@/components/Select/accountSelect.vue";
import numberInput from "@/components/Input/numberInput.vue";
import journalWordSelect from "@/components/Select/journalWordSelect.vue";
import journalCurrencySelect from "@/components/Select/journalCurrencySelect.vue";
import journalCurrencyPanel from "@/components/Panel/journalCurrencyPanel.vue";
import attachmentPanel from "@/components/Attachment/index.vue";
import printDialog from "@/components/Print/index.vue";
export default {
  components: {
    toolbar,
    dimensionValueSelect,
    dimensionValuePanel,
    accountSelect,
    numberInput,
    journalWordSelect,
    journalCurrencySelect,
    journalCurrencyPanel,
    attachmentPanel,
    printDialog,
  },
  data() {
    return {
      journal: {
        id: null,
        date: null,
        numberprefixId: "",
        number: "",
        items: [],
      },
      rules: {
        date: [
          {
            type: "date",
            required: true,
            message: "请选择日期",
            trigger: "change",
          },
        ],
        number: [
          { required: true, message: "凭证号为必填项", trigger: "change" },
        ],
      },
      tableRules: {
        summary: [{ required: true, message: "摘要为必填项" }],
        accountId: [{ required: true, message: "科目为必填项" }],
      },
      isModifying: false,
      currentAccount: null,
      mergeFooterItems: [{ row: 1, col: 2, rowspan: 1, colspan: 6 }],
      editAttachmentDrawer: false,
    };
  },
  methods: {
    getData() {
      if (!this.id) {
        this.setDefaultInfo();
        return;
      }
      getJournal(this.id).then((res) => {
        this.journal = res || {};
      });
    },
    handleRefresh() {
      this.getData();
    },
    handleReturnList() {
      if (this.isModifying) {
        this.$confirm("当前数据为保存，是返回列表?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            this.$router.push({
              name: "Journal",
            });
          })
          .catch(() => {});
      } else {
        this.$router.push({
          name: "Journal",
        });
      }
    },
    handleAddNew() {
      let item = this.defaultJournalItem();

      this.$refs.xTable.insertAt(item, -1);
      this.journal.items.push(item);
    },
    handleDelete({ ids, rows }) {
      if (!rows || rows.length == 0) return;
      for (let i = 0; i < rows.length; i++) {
        let row = rows[i];
        if (row.id) {
          deleteJournal(row.id).then((res) => {
            if (!res) return;
            if (i == rows.length - 1) {
              this.$notify({
                title: "成功",
                message: "删除成功",
                type: "success",
                position: "bottom-right",
              });
              this.getJournal();
            }
          });
        } else {
          this.$refs.xTable.remove(row);
          this.journal.items.remove(row);
        }
      }
    },
    handleApprove(approved) {},
    async handleSubmit() {
      let rows = this.getRightfulItems();

      if (rows.length == 0) {
        this.$notify({
          title: "提示",
          message: "没有需要保存的数据",
          type: "warning",
          position: "bottom-right",
        });
        return;
      }

      const errMap = await this.$refs.xTable
        .validate(rows)
        .catch((errMap) => errMap);

      if (!errMap) {
        this.saveData();
      }
    },
    saveData() {
      let rows = this.getRightfulItems();

      for (let i = 0; i < rows.length; i++) {
        rows[i].index = i + 1;
      }
      this.journal.items = rows;

      addJournal(this.journal).then((res) => {
        if (res) {
          this.journal = res;
          this.$notify({
            title: "成功",
            message: "保存成功",
            type: "success",
            position: "bottom-right",
          });
        }
      });
    },
    handleCellEnableEdit({ row, rowIndex, column, columnIndex }) {
      if (column.property == "dimensionGroupValueId") {
        if (
          !row.currentAccount ||
          !row.currentAccount.dimensionItems ||
          row.currentAccount.dimensionItems.length == 0
        )
          return false;

        return true;
      }

      if (column.property == "currencyId") {
        if (!row.currentAccount || !row.currentAccount.isForeignCurrency)
          return false;

        return true;
      }

      return true;
    },
    handleCellClick() {},
    defaultJournalItem() {
      return {
        summary: null,
        accountId: null,
        direction: null,
        amount: null,
        debitAmount: null,
        creditAmount: null,
        dimensionGroupValueId: null,
        dimensionGroupValueItems: [],
        currencyId: null,
        currencyName: null,
        currentAccount: { dimensionItems: [] },
        exchangeRate: null,
        accountFullName: null,
      };
    },
    handleFooterData({ columns, data }) {
      let result = [];

      let subTotalRow = columns.map((column, _columnIndex) => {
        if (_columnIndex === 0) {
          return "";
        }

        if (_columnIndex === 1) {
          return "";
        }
        if (
          [
            "summary",
            "accountId",
            "dimensionGroupValueId",
            "currencyId",
          ].includes(column.property)
        ) {
          return "";
        }

        let total = 0;
        data.forEach((item) => {
          if (item[column.property]) total = total + +item[column.property];
        });
        return total.toMoney();
      });

      result.push(subTotalRow);
      return result;
    },
    handleAccountChange(row, node) {
      let account = node.node;
      row.currentAccount = account;
      row.accountFullName = account.fullName;
      this.setTableColums();
    },
    handleCurrencyChange(row, value) {
      row.currencyId = value.currencyId;
      row.currencyName = value.currencyName;
      row.exchangeRate = value.exchangeRate;
      row.amountFr = value.amountFr;
      row.amount = value.amount;

      if (!row.debitAmount && !row.creditAmount) {
        row.debitAmount = value.amount;
        row.direction = 1;
      } else {
        row.debitAmount = row.debitAmount ? value.amount : "";
        row.creditAmount = row.creditAmount ? value.amount : "";
        row.direction = row.debitAmount ? 1 : -1;
      }
    },
    setTableColums() {
      let showDimensionColumn = false;
      let showCurrencyColumn = false;

      for (let i = 0; i < this.journal.items.length; i++) {
        let row = this.journal.items[i];
        if (!row.currentAccount) {
          continue;
        }

        if (
          row.currentAccount.dimensionItems &&
          row.currentAccount.dimensionItems.length > 0
        )
          showDimensionColumn = showCurrencyColumn || true;

        if (row.currentAccount.isForeignCurrency)
          showCurrencyColumn = showCurrencyColumn || true;
      }

      if (showDimensionColumn)
        this.$refs.xTable.showColumn(
          this.$refs.xTable.getColumnByField("dimensionGroupValueId")
        );
      else
        this.$refs.xTable.hideColumn(
          this.$refs.xTable.getColumnByField("dimensionGroupValueId")
        );

      if (showCurrencyColumn)
        this.$refs.xTable.showColumn(
          this.$refs.xTable.getColumnByField("currencyId")
        );
      else
        this.$refs.xTable.hideColumn(
          this.$refs.xTable.getColumnByField("currencyId")
        );
    },
    setDefaultInfo() {
      this.journal.date = new Date();
      if (this.journal.items.length > 0) return;
      //默认插四行数据
      for (let i = 0; i < 4; i++) {
        let item = this.defaultJournalItem();
        this.journal.items.push(item);
      }
    },
    setDefaultNumber() {
      if (!this.journal.date) return;
      let period = this.journal.date.toPeriod();
      let numberPrefixId = this.journal.numberprefixId;

      if (
        !period ||
        !numberPrefixId ||
        numberPrefixId == "00000000-0000-0000-0000-000000000000"
      )
        return;

      getJournalNextNumber(numberPrefixId, period).then((res) => {
        if (res) this.journal.number = res;
      });
    },
    handleDateChange() {
      this.setDefaultNumber();
    },
    handleNumberPrefixChange() {
      this.setDefaultNumber();
    },
    handleDimensionValueChange(row, values) {
      row.dimensionGroupValueItems = [];

      for (let i = 0; i < values.length; i++) {
        let dimensionValue = values[i];
        row.dimensionGroupValueItems.push({
          label: dimensionValue.label,
          dataSourceType: dimensionValue.dataSourceType,
          tagId: dimensionValue.tagId,
          value: dimensionValue.value,
        });
      }
    },
    getRightfulItems() {
      let result = [];
      if (!this.journal.items || this.journal.items.length == 0) return result;

      for (let i = 0; i < this.journal.items.length; i++) {
        let item = this.journal.items[i];

        if (
          item.summary ||
          item.accountId ||
          (item.dimensionGroupValueItems &&
            item.dimensionGroupValueItems.length > 0) ||
          item.currencyId ||
          item.debitAmount ||
          item.creditAmount
        )
          result.push(item);
      }

      return result;
    },
    handleAmountChange(row, direction) {
      row.direction = direction;
      if (direction == 1) {
        row.creditAmount = null;
        row.amount = row.debitAmount;
      } else {
        row.debitAmount = null;
        row.amount = row.creditAmount;
      }
    },
    handleAttachment() {
      this.editAttachmentDrawer = true;
    },
    handlePrint() {
      this.$refs.printPanel.showDialog();
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.getData();
    });
  },
  computed: {
    id() {
      return this.$route.query.id;
    },
    readonly() {
      return false;
    },
  },
  watch: {},
};
</script>
<style scoped></style>
